﻿/*
 * LINQ to LDAP
 * http://linqtoldap.codeplex.com/
 * 
 * Copyright Alan Hatter (C) 2010-2012
 * alan.hatter@gmail.com - http://hattercoding.blogspot.com/
 * 
 * This project is subject to licensing restrictions. Visit http://linqtoldap.codeplex.com/license for more information.
 */

using System.Collections;
using System.Collections.Generic;
using System.DirectoryServices.Protocols;
using LinqToLdap.Transformers;

namespace LinqToLdap.Collections
{
    internal class SearchResponseEnumerator<T> : IEnumerable<T>, IEnumerator<T>
    {
        private SearchResultEntryCollection _entries;
        private List<SearchResultEntry> _enumerableEntries;
        private IResultTransformer _resultTransformer;
        private int _position = -1;
        private readonly int _count;

        public SearchResponseEnumerator(SearchResultEntryCollection entries, IResultTransformer resultTransformer)
        {
            _resultTransformer = resultTransformer;
            _entries = entries;
            _count = entries != null ? entries.Count : 0;
        }

        public SearchResponseEnumerator(IResultTransformer resultTransformer, List<SearchResultEntry> entries)
        {
            _resultTransformer = resultTransformer;
            _enumerableEntries = entries;
            _count = _enumerableEntries != null ? _enumerableEntries.Count : 0;
        }

        private SearchResultEntry Get(int index)
        {
            return _entries != null ? _entries[index] : _enumerableEntries[index];
        }

        public bool MoveNext()
        {
            _position++;
            return _position < _count;
        }

        public void Reset()
        {
            _position = -1;
        }

        T IEnumerator<T>.Current
        {
            get { return (T)Current; }
        }

        public object Current
        {
            get
            {
                var entry = Get(_position);
                return _resultTransformer.Transform(entry);
            }
        }

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return this;
        }

        public IEnumerator GetEnumerator()
        {
            return this;
        }

        public void Dispose()
        {
            _entries = null;
            _enumerableEntries = null;
            _resultTransformer = null;
        }
    }
}
